package middleware

import (
	"context"
	"fmt"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
	"server/internal/errors"
	"server/internal/service"
	"server/internal/tool"
)

func AdminAuthHandler(r *ghttp.Request) {
	ctx := r.GetCtx()

	// 权限URI
	route := tool.BuildAuthRoute(r.Method, r.Request.URL.Path)

	//不需要验证登录的路由地址
	if checkExceptLoginRoute(ctx, route, "router.admin.exceptLogin") {
		r.Middleware.Next()
		return
	}

	//获取登录用户信息
	adminAuthInfo, err := service.SystemAuthorityCache().GetUserCacheAuthData(ctx)
	if adminAuthInfo.Id == 0 || err != nil {
		Response(r, errors.CodeNoLogin, "未登录", g.Array{})
		r.ExitAll()
		return
	}

	//同一个账号是否允许多个设备登录
	allowAdminMultipleLogin, _ := g.Cfg().Get(ctx, "system.allowAdminMultipleLogin")

	// 检测账号是否重复登录
	sessionID, _ := service.SystemSession().GetSessionID(ctx)
	if allowAdminMultipleLogin.Bool() == false && adminAuthInfo.RememberToken != sessionID {
		//删除用户session信息
		_ = service.SystemSession().RemoveAll(ctx)
		g.Log().Errorf(ctx, "account again login，auto logout，requestSessionID[%s],lastSessionID[%s]", sessionID, adminAuthInfo.RememberToken)
		Response(r, errors.CodeNoLogin, "您的账号已在其他地方登录，请重新登录！", g.Array{})
		r.ExitAll()
		return
	}

	//不需要验证权限的路由地址
	if checkExceptAuthRoute(ctx, route, "router.admin.exceptAuth") {
		r.Middleware.Next()
		return
	}

	//路由通过
	if service.SystemAuthority().HasPermissionRoute(ctx, route) {
		r.Middleware.Next()
		return
	}

	Response(r, errors.CodeNoPermission, fmt.Sprintf("无权访问接口[%s]", route), g.Array{})
	r.ExitAll()
}

// 判断是否是不需要验证登录的路由地址
func checkExceptLoginRoute(ctx context.Context, route string, configKey string) bool {
	config, err := g.Cfg().Get(ctx, configKey)
	if err != nil {
		return false
	}
	for _, item := range config.Strings() {
		if route == item {
			return true
		}
	}
	return false
}

// 判断是否是不需要验证权限的路由地址
func checkExceptAuthRoute(ctx context.Context, route string, configKey string) bool {
	config, err := g.Cfg().Get(ctx, configKey)
	if err != nil {
		return false
	}
	for _, item := range config.Strings() {
		if route == item {
			return true
		}
	}
	return false
}
